﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace PUCLibrary
{
    [Serializable]
    public class Horario
    {
        public List<Modulo> Modulos { get; private set; }
        private string[] moduloHora;  //Guarda el horario en formato {"L-W:3", "V:3"}  (solucion "parche" temporal)
        private string[] sala;  //Guarda el tipo la sala en formato {"A3", "N17"}   (solucion "parche" temporal)

        /// <param name="moduloHora">Ej: {"L-W:3", "V:3"}</param>
        /// <param name="tipoModulo">Ej: {"CAT", "AYUD"}</param>
        /// <param name="sala">Ej: {"A3", "N17"}</param>
        public Horario(string[] moduloHora, string[] tipoModulo, string[] sala)
        {
            if (moduloHora == null || tipoModulo == null || sala == null)
                throw new NullReferenceException((moduloHora == null) ? "modulos" : ((tipoModulo == null) ? "tipoModulo" : "sala"));
            if (moduloHora.Length != tipoModulo.Length && tipoModulo.Length != sala.Length)
                throw new ArgumentException("Error parseando horario: modulos[], tipoModulo[], y sala[] son de distinto largo.");
            
            if (moduloHora[0] == "Horario Especial" || moduloHora[0] == "(Por fijar)" || moduloHora[0] == "(Sin actividades)" || moduloHora[moduloHora.Length-1] == "(No válido)")
            {
                Modulos = new List<Modulo>();
                this.moduloHora = moduloHora;
                this.sala = sala;
                return;
            }

            this.moduloHora = moduloHora;   //Esto es temporal hasta q arregle get{Modulo,Sala}String()
            this.sala = sala;

            //Parseamos los modulos como corresponde:
            Modulos = new List<Modulo>();
            for (int i = 0; i < moduloHora.Length; i++) //foreach horario
            {
                string[] moduloSubsSinPtoComa = moduloHora[i].Split(';');   //Para parsear horarios del tipo "L-W:1;V:4"
                foreach (string item in moduloSubsSinPtoComa)
                {
                    string[] moduloSub = item.Split(':');   //Para parsear la parte "L-W:1"
                    if (moduloSub.Length != 2)
                        throw new ArgumentException("Error parseando horario: " + moduloHora[i]);

                    string[] dias = moduloSub[0].Split('-');    //Ej: {"L", "W"}
                    List<string> mods = new List<string>();
                    if (moduloSub[1].Contains(" a "))   //Ej: {"4 a 6"}, debemos rellenar 4,5, y 6.
                    {
                        int start = Int32.Parse(moduloSub[1].Split(new string[]{" a "}, StringSplitOptions.None)[0].Reverse().ToArray()[0].ToString());   //Horrible, lo se! Se me acaban los nombres pa variables!
                        int end = Int32.Parse(moduloSub[1].Split(new string[] { " a " }, StringSplitOptions.None)[1].Substring(0,1));

                        //mods = new string[end - start + 1];     //(Espero que el que lea este codigo no sea un asesino serial que sabe donde vivo...)
                        for (int m = start; m <= end; m++)
                            //mods[m - start] = m.ToString();
                            mods.Add(m.ToString());

                        moduloSub[1] = moduloSub[1].Replace("" + start + " a " + end, ""); //Sacamos y seguimos parseando. Tiene sentido con, por ej: {"2 a 4,6,7"}
                    }
                    
                    mods.AddRange(moduloSub[1].Split(new char[]{','}, StringSplitOptions.RemoveEmptyEntries)); //Ej: {"3,4"}

                    foreach (var dia in dias)   //Permutamos todas las combinaciones de modulo
                    {
                        foreach (var mod in mods)
                        {
                            int modNum = Int32.Parse(mod.Trim());
                            Modulos.Add(new Modulo(dia, modNum, sala[i], tipoModulo[i]));
                        }
                    }
                }
            }
        }

        /// <summary>
        /// Retorna los modulos de la seccion en formato: "L-W:3, V:3"
        /// </summary>
        public string getModuloString()
        {
            //if (moduloHora != null)
            return String.Join(" || ", moduloHora);    //TODO: Esto deberia hacerlo usando la List<Modulo> en vez de esas variables parche
            //else
            //{
            //    //Logger.Instance.Log("Error al leer un horario 'null'. ");
            //    return "";
            //}
        }

        public string getSalaString()
        {
            //if (sala != null)
                return String.Join(" || ", sala);  //TODO: Esto deberia hacerlo usando la List<Modulo> en vez de esas variables parche
            //else
            //{
            //    //Logger.Instance.Log("Error al leer una sala 'null'. ");
            //    return "";
            //}
        }
    }
}
